﻿using Microsoft.Extensions.Options;
using Shop.Core.Redis;
using SKIT.FlurlHttpClient.Wechat.Api;
using SKIT.FlurlHttpClient.Wechat.Api.Models;

namespace Shop.Core.WeChat
{
    /// <summary>
    /// 
    /// </summary>
    public class AccessToken
    {
        private readonly IRedisProvider _redisProvider;

        private readonly WeChatConfig _weChatConfig;

        public AccessToken(IRedisProvider redisProvider
            , WeChatConfig weChatConfig)
        {
            _weChatConfig = weChatConfig;
            _redisProvider = redisProvider;
        }

        /// <summary>
        /// 获取小程序token
        /// </summary>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public async Task<string> GetWxOpenAccessToken()
        {
            var data = await _redisProvider.StringGetAsync("AppletToken");
            if (!string.IsNullOrEmpty(data))
                return data;
            else
            {
                var client = WeChatApiHttpClientFactory.CreateWxOpenClient(_weChatConfig);
                var request = new CgibinTokenRequest();
                var response = await client.ExecuteCgibinTokenAsync(request);
                if (response.IsSuccessful())
                {
                    // 提前十分钟过期，以便于系统能及时刷新，防止因在过期临界点时出现问题
                    await _redisProvider.StringSetAsync("AppletToken", response.AccessToken, new TimeSpan(0, 10, 0));
                    return response.AccessToken;
                }
                else
                    throw new Exception($"获取凭证失败；错误码：{response.ErrorCode}；错误内容：{response.ErrorMessage}");
            }
        }

        /// <summary>
        /// 刷新token并返回新的token
        /// </summary>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public async Task<string> RefreshWxOpenAccessToken()
        {
            var client = WeChatApiHttpClientFactory.CreateWxOpenClient(_weChatConfig);
            var request = new CgibinTokenRequest();
            var response = await client.ExecuteCgibinTokenAsync(request);
            if (response.IsSuccessful())
            {
                await _redisProvider.KeyDelAsync("AppletToken");
                // 提前十分钟过期，以便于系统能及时刷新，防止因在过期临界点时出现问题
                await _redisProvider.StringSetAsync("AppletToken", response.AccessToken, new TimeSpan(0, 10, 0));
                return response.AccessToken;
            }
            else
                throw new Exception($"获取凭证失败；错误码：{response.ErrorCode}；错误内容：{response.ErrorMessage}");
        }

        /// <summary>
        /// 获取公众号Token
        /// </summary>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public async Task<string> GetWeXinAccessToken()
        {
            var data = await _redisProvider.StringGetAsync("WeXinToken");
            if (!string.IsNullOrEmpty(data))
                return data;
            else
            {
                var client = WeChatApiHttpClientFactory.CreateWeXinClient(_weChatConfig);
                var request = new CgibinTokenRequest();
                var response = await client.ExecuteCgibinTokenAsync(request);
                if (response.IsSuccessful())
                {
                    // 提前十分钟过期，以便于系统能及时刷新，防止因在过期临界点时出现问题
                    await _redisProvider.StringSetAsync("WeXinToken", response.AccessToken, TimeSpan.FromSeconds(response.ExpiresIn - 600));
                    return response.AccessToken;
                }
                else
                    throw new Exception($"获取凭证失败；错误码：{response.ErrorCode}；错误内容：{response.ErrorMessage}");
            }
        }
    }
}
